package threadPool;

import jdk.nashorn.internal.ir.CallNode;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class MyThreadPool {

    //任务队列
    private BlockingQueue<Runnable> taskQueue;

    //线程集合

}
@Slf4j
class BlockingQueue<T>{
    //1.任务队列
    private Deque<T> queue=new ArrayDeque<T>();

    //2.锁
    private ReentrantLock lock =new ReentrantLock();

    //3.生产者条件变量：生产者生产时，队列有可能full
    private Condition fullWaitSet=lock.newCondition();

    //4.消费者条件变量：消费者消费时，队列有可能为empty
    private Condition emptyWaitSet=lock.newCondition();

    //5.容量
    private int capacity;

    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }

    //阻塞获取
    public T take(){
        lock.lock();
        try {
            while(queue.isEmpty()){
                //如果队列为空，则到消费者条件里等待
                try {
                    log.debug("等待生产者生产");
                    emptyWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果不为空，则取出第一个，并唤醒生产者条件
            T t = queue.removeFirst();
            fullWaitSet.signal();
            return t;
        } finally {
            lock.unlock();
        }
    }

    //阻塞添加
    public void put(T task){
        lock.lock();
        try {
            while(queue.size()==capacity){
                //如果队列满了，则到生产者条件里等待
                try {
                    log.debug("等待加入到任务队列{}",task);
                    fullWaitSet.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果队列没满，则把元素加到队列尾，并唤醒消费者条件
            log.debug("加入到任务队列{}",task);
            queue.addLast(task);
            emptyWaitSet.signal();
        } finally {
            lock.unlock();
        }
    }
}
